#include "radiometer.h"

#include <QDebug>

//const int RADIO_NSUPROTOCOL_LEN = 160;

RadioMeter* RadioMeter::instance = new RadioMeter();

RadioMeter::RadioMeter(QObject* parent)
    :m_port(new QSerialPort){
    //接收到对应的数据头，调用对应的解析数据函数
    m_parseMap["NS"] = [this](const QByteArray& ary){ this->parseNSU(ary);};
    m_parseMap["ST"] = [this](const QByteArray& ary){ this->parseSTA(ary);};
    m_parseMap["AO"] = [this](const QByteArray& ary){ this->parseAOD(ary);};
    //m_parseMap["SE"] = [this](const QByteArray& ary){ this->parseSETDATETIME(ary);};
    //m_parseMap["DA"] = [this](const QByteArray& ary){ this->parseDATE(ary);};
   //m_parseMap["TI"] = [this](const QByteArray& ary){ this->parseTIME(ary);};
    m_parseMap["LA"] = [this](const QByteArray& ary){ this->parseLAT(ary);};
    m_parseMap["LO"] = [this](const QByteArray& ary){ this->parseLON(ary);};
    m_parseMap["Az"] = [this](const QByteArray& ary){ this->parseAZ(ary);};
    m_parseMap["Ei"] = [this](const QByteArray& ary){ this->parseEI(ary);};
    //m_parseMap["RA"] = [this](const QByteArray& ary){ this->parseRAIN(ary);};
    m_parseMap["SY"] = [this](const QByteArray& ary){ this->parseSYSTEMRESET(ary);};
    m_parseMap["SE"] = [this](const QByteArray& ary){ this->parseSETTIMESPAN(ary);};


    /*connect(this, &RadioMeter::protocolNSU, this, [=](const QByteArray& ary){
        QString str = ary;
        QStringList protocoList = str.split(',');
        RadioMeterNSUProtocolAll protocol;
        QDate date = QDate::fromString(protocoList[1], "dd/MM/yyyy");
        QTime time = QTime::fromString(protocoList[2], "hh:mm:ss");
        protocol.dateTime = QDateTime(date, time);
        protocol.sun1020 = protocoList[3].toInt();
        protocol.sunI1640 = protocoList[4].toInt();
        protocol.sun870 = protocoList[5].toInt();
        protocol.sun670 = protocoList[6].toInt();
        protocol.sun440 = protocoList[7].toInt();
        protocol.sun500 = protocoList[8].toInt();
        protocol.sunI1020 = protocoList[9].toInt();
        protocol.sun936 = protocoList[10].toInt();
        protocol.sun380 = protocoList[11].toInt();
        protocol.sun340 = protocoList[12].toInt();
        protocol.temperature = protocoList[33].toDouble();
        emit updateView(protocol);
    });*/
}
//解析NSU协议
void RadioMeter::parseNSU(const QByteArray &ary)
{
    QString str = ary;
    QStringList protocoList = str.split(',');
    //协议三次太阳辐射计测量值的间隔
    int interval = 10;
    RadioMeterNSUProtocolAll protocol;
    QDate date = QDate::fromString(protocoList[1], "dd/MM/yyyy");
    QTime time = QTime::fromString(protocoList[2], "hh:mm:ss");
    protocol.dateTime = QDateTime(date, time);

    protocol.sun1020 = (protocoList[3].toDouble() + protocoList[3 + interval].toDouble() + protocoList[3 + interval*2].toDouble())/3;
    protocol.sunI1640 = (protocoList[4].toDouble()+ protocoList[4 + interval].toDouble() + protocoList[4 + interval*2].toDouble())/3;
    protocol.sun870 = (protocoList[5].toDouble()+ protocoList[5 + interval].toDouble() + protocoList[5 + interval*2].toDouble())/3;
    protocol.sun675 = (protocoList[6].toDouble()+ protocoList[6 + interval].toDouble() + protocoList[6 + interval*2].toDouble())/3;
    protocol.sun440 = (protocoList[7].toDouble()+ protocoList[7 + interval].toDouble() + protocoList[7 + interval*2].toDouble())/3;
    protocol.sun500 = (protocoList[8].toDouble()+ protocoList[8 + interval].toDouble() + protocoList[8 + interval*2].toDouble())/3;
    protocol.sunI1020 = (protocoList[9].toDouble()+ protocoList[9 + interval].toDouble() + protocoList[9 + interval*2].toDouble())/3;
    protocol.sun937 = (protocoList[10].toDouble()+ protocoList[10 + interval].toDouble() + protocoList[10 + interval*2].toDouble())/3;
    protocol.sun380 = (protocoList[11].toDouble()+ protocoList[11 + interval].toDouble() + protocoList[11 + interval*2].toDouble())/3;
    protocol.sun340 = (protocoList[12].toDouble()+ protocoList[12 + interval].toDouble() + protocoList[12 + interval*2].toDouble())/3;
    protocol.headTemperature = protocoList[33].toDouble();
    protocol.ambientTemperature = protocoList[34].toDouble();
    protocol.airPressure = protocoList[35].toDouble();
    emit updateView_NSU(protocol);
}
//解析STA协议
void RadioMeter::parseSTA(const QByteArray &ary)
{
    QString str = ary;
    QStringList protocolList = str.split(',');
    RadioMeterSTAProtocolAll protocol;

    QDate date = QDate::fromString(protocolList[1], "dd/MM/yyyy");
    QTime time = QTime::fromString(protocolList[2], "hh:mm:ss");
    protocol.dateTime = QDateTime(date, time);

    protocol.radioMeterStatus = protocolList[3].split(':')[1];
    protocol.temperature = protocolList[4].split(':')[1].toDouble();
    protocol.humidity = protocolList[5].split(':')[1].toDouble();
    protocol.voltage = protocolList[6].split(':')[1].toDouble();
    protocol.errCode = protocolList[7].split(':')[1];
    protocol.heightAngle = protocolList[8].split(':')[1].toDouble();//高度角
    protocol.azimuthAngle = protocolList[9].split(':')[1].toDouble();//方位角
    protocol.turnTableStatus = protocolList[10].split(':')[1];
    protocol.powerStatus = protocolList[11];

    emit updateView_STA(protocol);

}

//解析AOD协议
void RadioMeter::parseAOD(const QByteArray &ary)
{
    QString str = ary;
    QStringList protocoList = str.split(',');

    RadioMeterAODProtocolAll protocol;
    QDate date = QDate::fromString(protocoList[1], "yyyy/MM/dd");
    QTime time = QTime::fromString(protocoList[2], "hh:mm:ss");
    protocol.dateTime = QDateTime(date, time);

    protocol.sun1020 = protocoList[3].toDouble() ;
    protocol.sunI1640 = protocoList[4].toDouble();
    protocol.sun870 = protocoList[5].toDouble();
    protocol.sun675 = protocoList[6].toDouble();
    protocol.sun440 = protocoList[7].toDouble();
    protocol.sun500 = protocoList[8].toDouble();
    protocol.sunI1020 = protocoList[9].toDouble();
    protocol.sun937 = protocoList[10].toDouble();
    protocol.sun380 = protocoList[11].toDouble();
    protocol.sun340 = protocoList[12].toDouble();
    protocol.PWV = protocoList[13].toDouble();

    emit updateView_AOD(protocol);

}

// void RadioMeter::parseSETDATETIME(const QByteArray &ary)
// {
// }

// void RadioMeter::parseDATE(const QByteArray &ary)
// {
// }

// void RadioMeter::parseTIME(const QByteArray &ary)
// {
// }

void RadioMeter::parseLAT(const QByteArray &ary)
{
    QString lat = ary;
    QStringList list = lat.split(",");
    lat = list[1];
    emit updateView_LAT(lat);
}

void RadioMeter::parseLON(const QByteArray &ary)
{
    QString lon = ary;
    QStringList list = lon.split(",");
    lon = list[1];
    emit updateView_LON(lon);
}

// void RadioMeter::parseALTI(const QByteArray &ary)
// {
// }

void RadioMeter::parseAZ(const QByteArray &ary)
{

}

void RadioMeter::parseEI(const QByteArray &ary)
{

}

// void RadioMeter::parseRAIN(const QByteArray &ary)
// {
// }

void RadioMeter::parseSYSTEMRESET(const QByteArray &ary)
{

}

void RadioMeter::parseSETTIMESPAN(const QByteArray &ary)
{

}



RadioMeter *RadioMeter::getInstance()
{
    return instance;
}

bool RadioMeter::openDevice(QString portName)
{
    m_port->setPortName(portName);
    m_port->setBaudRate(9600);
    m_port->setDataBits(QSerialPort::Data8);
    m_port->setStopBits(QSerialPort::OneStop);
    m_port->setParity(QSerialPort::NoParity);
    m_port->setFlowControl(QSerialPort::NoFlowControl);
    m_port->setReadBufferSize(4096);
    if(m_port->open(QSerialPort::ReadWrite)){
        qDebug()<<"打开成功";
        connect(this->m_port, &QSerialPort::errorOccurred, this, [=](QSerialPort::SerialPortError err){
            qDebug()<<"错误信息 : "<<this->m_port->errorString();
        });
        connect(this->m_port, &QSerialPort::readyRead, this, [=](){
            //可读或者m_readBuffer中还有数据，都说明还有数据，继续解析。
            if(this->m_port->bytesAvailable() || !m_readBuffer.isEmpty()){
                QByteArray ary = this->m_port->readAll();
                qDebug()<<"rec arr:"<<ary<<"ary.length: "<<ary.length();
                this->m_readBuffer.append(ary);

                if(m_readBuffer.length() > 2){
                    QByteArray head = m_readBuffer.left(2);
                    qDebug()<<"m_readBuffer:"<<m_readBuffer<<"m_readBuffer.length: "<<m_readBuffer.length();
                    if(head == "NS"){
                        if(m_readBuffer.length() >= RADIO_NSUPROTOCOL_LEN){
                            m_parseMap["NS"](m_readBuffer.mid(0, RADIO_NSUPROTOCOL_LEN));
                            m_readBuffer.remove(0, RADIO_NSUPROTOCOL_LEN);
                        }
                    }
                    //此协议不定长？
                    else if(head == "ST"){
                        if(m_readBuffer.length() >= RADIO_STAPROTOCOL_LEN){
                            int end = m_readBuffer.indexOf("OK");
                            if(end > 0){
                                m_parseMap["ST"](m_readBuffer.mid(0, end + 2));
                                m_readBuffer.remove(0, end + 2);
                            }else if(m_readBuffer.indexOf("LOW") > 0){
                                end = m_readBuffer.indexOf("LOW");
                                m_parseMap["ST"](m_readBuffer.mid(0, end + 3));
                                m_readBuffer.remove(0, end + 3);
                            }
                        }
                    }else if(head == "AO"){
                        if(m_readBuffer.length() >= RADIO_AODPROTOCOL_LEN){
                            m_parseMap["AO"](m_readBuffer.mid(0, RADIO_AODPROTOCOL_LEN));
                        }
                    }
                }

                /*
                QByteArray ary = this->m_port->readAll();
                qDebug()<<"rec arr:"<<ary<<"ary.length: "<<ary.length();
                this->m_readBuffer.append(ary);
                int index = this->m_readBuffer.indexOf("NSU");
                //qDebug()<<"index:"<<index<<"  m_readBuffer:"<<this->m_readBuffer;
                // |多余数据|NSU|正确数据|，删除第一次NSU前的所有数据
                if(index > 0){
                    this->m_readBuffer.remove(0, index);
                }
                if(this->m_readBuffer.length() >= RADIOMETER_NSUPROTOCOL_LENGTH){
                    int index = this->m_readBuffer.indexOf("NSU");
                    qDebug()<<"index:"<<index<<"  m_readBuffer:"<<this->m_readBuffer;
                    if(index >= 0){
                        QByteArray result = this->m_readBuffer.mid(index, RADIOMETER_NSUPROTOCOL_LENGTH);
                        //qDebug()<<"result : "<<result;
                        emit protocolNSU(result);
                        this->m_readBuffer.remove(index, RADIOMETER_NSUPROTOCOL_LENGTH);
                    }
                }
                */
            }
        });
        return true;
    }

    return false;
}

void RadioMeter::closeDevice()
{
    m_port->close();
}

RadioMeter::~RadioMeter(){
    m_port->close();
}
